
#include <iostream>
#include <string>
#include <vector>
#include "pugixml.hpp"
#include <list>
#include "core.h"

const int ID_SIZE=4;




int main(int argc, char** argv)
{
	if (argc!=2) {
		cout << "Usage: meta-parser [FILENAME]\n";
		return -1;
	}
	

	std::vector<FundamentalTypeStruct> fundamentalTypes;
	vector<PointerTypeStruct> pointerTypes;
	vector<StructDesc> structures;
	vector<Field> fields;
	
	
	xml_document doc;
	xml_parse_result result=doc.load_file(argv[1]);
	if (result==NULL){
		std::cout<<"Error occured. Check the filename and try again.";
		return -1;
	}
	

	xml_node tools=doc.child("GCC_XML");


for (xml_node tool = tools.child("FundamentalType"); tool; tool = tool.next_sibling("FundamentalType"))
{
	FundamentalTypeStruct* fts=new FundamentalTypeStruct(string(tool.attribute("id").value()), string(tool.attribute("name").value()), (size_t)tool.attribute("size").as_int(), (size_t)tool.attribute("align").as_int());
	fundamentalTypes.push_back (*fts);
}

for (xml_node tool = tools.child("PointerType"); tool; tool = tool.next_sibling("PointerType"))
{
	PointerTypeStruct* pts=new PointerTypeStruct(string(tool.attribute("id").value()), string(tool.attribute("type").value()), (size_t)tool.attribute("size").as_int(), (size_t)tool.attribute("align").as_int());
	pointerTypes.push_back (*pts);
}


for (xml_node tool=tools.child ("Struct"); tool; tool=tool.next_sibling ("Struct")){
	StructDesc* so=new StructDesc(string(tool.attribute ("name").value()), \
	                            string(tool.attribute("id").value()));
	structures.push_back (*so);
	
	
}

for (xml_node tool=tools.child ("Class"); tool; tool=tool.next_sibling ("Class")){
	StructDesc* so=new StructDesc(string(tool.attribute ("name").value()), \
	                            string(tool.attribute("id").value()));
	structures.push_back (*so);
	
	
}



for (xml_node tool=tools.child("Field"); tool; tool=tool.next_sibling("Field")){
	Field* f=new Field(string(tool.attribute("id").value()),\
	                   string(tool.attribute("name").value()),\
			   string(tool.attribute("type").value()),\
	                   (size_t)tool.attribute("offset").as_int(),\
	                   string(tool.attribute("context").value()));
	fields.push_back(*f);
}
	



	
//	for (pugi::xml_node_iterator it = tools.begin(); it != tools.end(); ++it){
 //   std::cout << "Tool:";
//	std::cout<<"{tagname}"<<it->name()<<"{endof}";
//		string test=it->name();
//	
//	if (test=="FundamentalType"){
//		FundamentalTypeStruct* fts=new FundamentalTypeStruct(string(it->attribute("id").value()), string(it->attribute("name").value()), (size_t)it->attribute("size").as_int(), (size_t)it->attribute("align").as_int());
//			fundamentalTypes.push_back (*fts);
//	}



//	for (pugi::xml_attribute_iterator ait = it->attributes_begin(); ait != it->attributes_end(); ++ait)
//    {
//        std::cout << " " << ait->name()<< "=" << ait->value();
//    }

		
//	}	
//	for (vector<FundamentalTypeStruct>::iterator l=fundamentalTypes.begin(); l!=fundamentalTypes.end(); ++l){
//		cout<<(*l).name<< " " << (*l).id << " " << (*l).size <<" " << (*l).align<<endl;
//	}
	
//	for (vector<Field>::iterator l=fields.begin(); l!=fields.end(); ++l){
//		cout<<l->name<<" "<<l->context<<endl;
//	}

	
//	for (vector<StructDesc>::iterator l=structures.begin(); l!=structures.end(); ++l){
//		cout<<l->name<<" "<<l->id<<endl;
//	}






	vector<offsets_list> mojo;

	for (vector<StructDesc>::iterator l=structures.begin(); l!=structures.end();++l){
		offsets_list offs;
		for (vector<Field>::iterator m=fields.begin(); m!=fields.end(); ++m){
			if (m->context==l->id){
				for (vector<PointerTypeStruct>::iterator pts=pointerTypes.begin(); pts!=pointerTypes.end(); ++pts)
					{
						if (m->type==pts->id)
							offs.push_back(m->offset);
					}	
			}

		}
		mojo.push_back(offs);
	}

	for (vector<offsets_list>::iterator l=mojo.begin(); l!=mojo.end(); ++l){
		cout<<endl;
		for (offsets_list::iterator i=l->begin(); i!=l->end(); ++i)
			cout<<(*i)<< " ";
	}

	cout<<endl;
	return 0;


}


